#include "drv_uart.h"
#include "config.h"

RxStateType rx1s;
TxStateType tx1s;
UartDataType Rx1Data,Tx1Data,Tx1Cach;

void Debug_SendByte(u8 data)
{
	//M0P_UART1->ICR_f.TCCF = 0;
	while(!M0P_UART0->ISR_f.TXE);
	M0P_UART0->SBUF = data;
}
void Debug_Sendbuf(uint8_t *buf, uint8_t count)
{
    u8 i;
    for(i=0;i<count;i++)
    {
        Debug_SendByte(buf[i]);
    }
}

void ErrIntCallback(void)
{
}
void PErrIntCallBack(void)
{
}
void CtsIntCallBack(void)
{
}

void Uart_Timer1ms_Handle(void)
{
    if(tx1s.tdelayx1ms)
        tx1s.tdelayx1ms --;
    if(rx1s.tdelayx1ms)
    {
        rx1s.tdelayx1ms --;
        if(rx1s.tdelayx1ms == 0)
        {
            Rx1Data.count = Rx1Data.index;
            Rx1Data.index = 0;
            rx1s.rxs = UART_RX_STAT_fill;
        }
				
				
    }
}

void U1_TxIntCallback(void)
{
    tx1s.tdelayx1ms = UART_TX_DELAY;
    Tx1Data.index ++;
    if(Tx1Data.index<Tx1Data.count)
        M0P_UART0->SBUF = Tx1Data.buf[Tx1Data.index]; 
    else
    {
        Uart_DisableIrq(UARTCH0,UartTxEIrq);
    } 
}
void U1_RxIntCallback(void)
{
    rx1s.tdelayx1ms = UART_RX_DELAY;
    Rx1Data.buf[Rx1Data.index]=Uart_ReceiveData(UARTCH0);
    Rx1Data.index ++;
    if(Rx1Data.index >= UART_BUF_MAX)
    {
        Rx1Data.count = Rx1Data.index;
        Rx1Data.index = 0;
        rx1s.rxs = UART_RX_STAT_fill;
    }
}

void U1_SendBuf(uint8_t *buf, uint8_t count)
{
    uint8_t i;
    for(i=0;i<count;i++)
        Tx1Cach.buf[i] = buf[i];
    Tx1Cach.count = count;
    tx1s.cachs = UART_BUF_Filled;
}

void Config_Uart1(void)
{
    uint16_t u16Scnt = 0;
    stc_gpio_config_t stcGpioCfg;
    stc_uart_config_t  stcConfig;
    stc_uart_irq_cb_t stcUartIrqCb;
    stc_uart_multimode_t stcMulti;
    stc_uart_baud_t stcBaud;

    //en_uart_mmdorck_t enTb8;
    
    DDL_ZERO_STRUCT(stcGpioCfg);
    DDL_ZERO_STRUCT(stcConfig);
    DDL_ZERO_STRUCT(stcUartIrqCb);
    DDL_ZERO_STRUCT(stcMulti);
    DDL_ZERO_STRUCT(stcBaud);

    //UART1  
    stcGpioCfg.enDir = GpioDirOut;
    Gpio_Init(TX_PORT,TX_PIN,&stcGpioCfg);
    Gpio_SetAfMode(TX_PORT,TX_PIN,GpioAf1);//RS485 UART1 TX
    stcGpioCfg.enDir = GpioDirIn;
    Gpio_Init(RX_PORT,RX_PIN,&stcGpioCfg);
    Gpio_SetAfMode(RX_PORT,RX_PIN,GpioAf1);//RS485 UART1 RX 

    stcUartIrqCb.pfnRxIrqCb   = U1_RxIntCallback;
    stcUartIrqCb.pfnTxIrqCb   = U1_TxIntCallback;
    stcUartIrqCb.pfnRxFEIrqCb = ErrIntCallback;
    stcUartIrqCb.pfnPEIrqCb   = PErrIntCallBack;
    stcUartIrqCb.pfnCtsIrqCb  = CtsIntCallBack;
    stcConfig.pstcIrqCb = &stcUartIrqCb;
    stcConfig.bTouchNvic = TRUE;

    stcConfig.enRunMode = UartMode1;
    stcConfig.enStopBit = Uart1bit;  

    stcMulti.enMulti_mode = UartNormal;
    //enTb8 = UartEven;
    //Uart_SetMMDOrCk(UARTCH0,enTb8);
    stcConfig.pstcMultiMode = &stcMulti;
    
    Uart_Init(UARTCH0, &stcConfig);

    Uart_SetClkDiv(UARTCH0,Uart8Or16Div);
    stcBaud.u32Pclk = Sysctrl_GetPClkFreq();
    stcBaud.enRunMode = UartMode1;
    stcBaud.u32Baud = 38400;
    u16Scnt = Uart_CalScnt(UARTCH0,&stcBaud);
    Uart_SetBaud(UARTCH0,u16Scnt);
    
    Uart_EnableIrq(UARTCH0,UartRxIrq);
    Uart_ClrStatus(UARTCH0,UartRC);
    Uart_EnableFunc(UARTCH0,UartRx);  
}


void Uart_Process(void)
{
    uint8_t i;
    
    //uart1
    if(rx1s.rxs == UART_RX_STAT_fill)
    {
        Comm_Receive(Rx1Data.buf, Rx1Data.count);
        //Debug_Sendbuf(Rx1Data.buf, Rx1Data.count);
        rx1s.rxs = UART_RX_STAT_empty;
    }
    if((tx1s.bufs == UART_BUF_Filled)&&(tx1s.tdelayx1ms == 0))
    {
        if(tx1s.repeats)
        {
            tx1s.repeats --;
            Tx1Data.index = 0;
            M0P_UART0->SBUF = Tx1Data.buf[Tx1Data.index];
            tx1s.tdelayx1ms = UART_TX_DELAY;
            Uart_EnableIrq(UARTCH0,UartTxEIrq);
        }
        else
            tx1s.bufs = UART_BUF_empty;
    }
    else if((tx1s.cachs == UART_BUF_Filled)&&(tx1s.bufs == UART_BUF_empty))
    {
        for(i=0; i<Tx1Cach.count; i++)
            Tx1Data.buf[i] = Tx1Cach.buf[i];
        Tx1Data.count = Tx1Cach.count;
        tx1s.repeats = 1;
        tx1s.cachs = UART_BUF_empty;
        tx1s.bufs = UART_BUF_Filled;
    }
}
